package com.jyy.prefabricated.service;

import com.jyy.prefabricated.dto.BatchDto;
import com.jyy.prefabricated.entity.CoursePackage;
import com.jyy.prefabricated.entity.CourseWithBLOBs;
import com.jyy.prefabricated.entity.Exam;
import com.jyy.prefabricated.entity.ExamCourse;
import com.jyy.prefabricated.enums.BaseStatusEnum;
import com.jyy.prefabricated.enums.CourseTypeEnum;
import com.jyy.prefabricated.enums.ExamStatusEnum;
import com.jyy.prefabricated.enums.OrderTypeEnum;
import com.jyy.prefabricated.exception.CustomException;
import com.jyy.prefabricated.mapper.*;
import com.jyy.prefabricated.utils.DateUtils;
import com.jyy.prefabricated.vo.StudentExamPaperVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;


/**
 * @version 1.0.0
 * @author: zjj
 */
@Slf4j
@Service
@Transactional
public class ExamService {

    @Resource
    private ExamMapper examMapper;

    @Resource
    private StudentExamService studentExamService;

    @Resource
    private StudentExamMapper studentExamMapper;

    @Resource
    private ExamCourseMapper examCourseMapper;

    @Resource
    private CourseMapper courseMapper;

    @Resource
    private CourseCategoryMapper courseCategoryMapper;

    @Resource
    private CoursePackageMapper coursePackageMapper;

    /**
     * 新增
     *
     * @param exam
     * @return
     */
    public Integer insert(Exam exam) {
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Calendar c = Calendar.getInstance();
        c.setTime(new Date());
        c.add(Calendar.YEAR, +100);
        if (exam.getExamEndTime() == null || exam.getExamEndTime() == null) {
            exam.setExamStartTime(format.format(new Date()));
            exam.setExamEndTime("2121-01-01 00:00:00");
        }
        exam.setStatus(BaseStatusEnum.INVALID.getValue());
        exam.setExamStatus(ExamStatusEnum.BEFORE.getValue());
        examMapper.insert(exam);
        //线下课程
        if (exam.getCourseList().size() > 0) {
            for (int i = 0; i < exam.getCourseList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getCourseList().get(i));
                examCourse.setDeleted(false);
                examCourse.setGoodsType(OrderTypeEnum.COURSE.getValue());
                examCourseMapper.insert(examCourse);
            }
        }
        //文档课程
        if (exam.getDocumentCoursesList().size() > 0) {
            for (int i = 0; i < exam.getDocumentCoursesList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getDocumentCoursesList().get(i));
                examCourse.setDeleted(false);
                examCourse.setGoodsType(OrderTypeEnum.COURSE.getValue());
                examCourseMapper.insert(examCourse);
            }
        }
        //录播课程
        if (exam.getRecordingCoursesList().size() > 0) {
            for (int i = 0; i < exam.getRecordingCoursesList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getRecordingCoursesList().get(i));
                examCourse.setDeleted(false);
                examCourse.setGoodsType(OrderTypeEnum.COURSE.getValue());
                examCourseMapper.insert(examCourse);
            }
        }
        //课程包
        if (exam.getCoursePackageList().size() > 0) {
            for (int i = 0; i < exam.getCoursePackageList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getCoursePackageList().get(i));
                examCourse.setDeleted(false);
                examCourse.setGoodsType(OrderTypeEnum.COURSE_PACKAGE.getValue());
                examCourseMapper.insert(examCourse);
            }
        }
        return exam.getId();
    }

    /**
     * 更新
     *
     * @param exam
     * @return
     */
    public int update(Exam exam) {
        if (exam.getId() == null) {
            throw new CustomException("参数id不能为空");
        }
        examCourseMapper.deleteByexamId(exam.getId());
        //线下课程
        if (exam.getCourseList().size() > 0) {
            for (int i = 0; i < exam.getCourseList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getCourseList().get(i));
                examCourse.setDeleted(false);
                examCourseMapper.insert(examCourse);
            }
        }
        //文档课程
        if (exam.getDocumentCoursesList().size() > 0) {
            for (int i = 0; i < exam.getDocumentCoursesList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getDocumentCoursesList().get(i));
                examCourse.setDeleted(false);
                examCourseMapper.insert(examCourse);
            }
        }
        //录播课程
        if (exam.getRecordingCoursesList().size() > 0) {
            for (int i = 0; i < exam.getRecordingCoursesList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getRecordingCoursesList().get(i));
                examCourse.setDeleted(false);
                examCourseMapper.insert(examCourse);
            }
        }
        //课程包
        if (exam.getCoursePackageList().size() > 0) {
            for (int i = 0; i < exam.getCoursePackageList().size(); i++) {
                ExamCourse examCourse = new ExamCourse();
                examCourse.setExamId(exam.getId());
                examCourse.setCourseId(exam.getCoursePackageList().get(i));
                examCourse.setDeleted(false);
                examCourseMapper.insert(examCourse);
            }
        }

        examMapper.updateByPrimaryKeySelective(exam);

        return 0;
    }

    /**
     * 批量更新状态
     *
     * @param dto
     * @return
     */
    public int batchUpdateStatus(BatchDto dto) {
        if (dto.getIds().size() == 0) {
            throw new CustomException("参数id不能为空");
        }
        return examMapper.batchUpdateStatus(dto.getIds(), dto.getStatus());
    }

    /**
     * 批量删除
     *
     * @param dto
     * @return
     */
    public int batchDelete(BatchDto dto) {
        if (dto.getIds().size() == 0) {
            throw new CustomException("参数id不能为空");
        }
        return examMapper.batchDelete(dto.getIds());
    }

    /**
     * 删除
     *
     * @param id
     * @return
     */
    public int delete(Integer id) {
        Exam exam = examMapper.selectByPrimaryKey(id);
        exam.setDeleted(true);
        return examMapper.updateByPrimaryKeySelective(exam);
    }

    /**
     * 根据id查询
     *
     * @param id
     * @return
     */
    public Exam selectById(Integer id) {
        Exam exam = examMapper.selectByPrimaryKey(id);

        if (exam != null) {
            for (ExamCourse examCourse : exam.getGoodsList()) {

                //课程包
                if (examCourse.getGoodsType().equals(OrderTypeEnum.COURSE_PACKAGE.getValue())) {
                    CoursePackage coursePackage = coursePackageMapper.selectByPrimaryKey(examCourse.getCourseId());
                    exam.getCpList().add(coursePackage);
                } else {
                    CourseWithBLOBs course = courseMapper.selectByPrimaryKey(examCourse.getCourseId());
                    if (course.getType().equals(CourseTypeEnum.OFFLINE.getValue())) {
                        exam.getCsList().add(course);
                    } else if (course.getType().equals(CourseTypeEnum.DOCUMENT.getValue())) {
                        exam.getDcList().add(course);
                    } else {
                        exam.getRcList().add(course);
                    }

                }
            }
        }
        return exam;
    }

    /**
     * 根据参数查询列表
     *
     * @param name       考试名称
     * @param projectId  项目id
     * @param pointId    考核点id
     * @param examStatus 考试状态
     * @param status     发布状态
     * @param startDate  考试开始时间
     * @param endDate    考试结束时间
     * @return
     */
    public List<Exam> selectByParams(String name, Integer projectId, Integer pointId, Integer examStatus, Integer status, String startDate, String endDate ,Integer trainingOrganizationId) {
        return examMapper.selectByParams(name, projectId, pointId, examStatus, status, startDate, endDate ,trainingOrganizationId);
    }


    /**
     * 检查考试状态，并更新状态
     */
    public void checkExamStatus() {
        Date now = new Date();
        List<Exam> exams = new ArrayList<>();
        List<Exam> waitStartExam = examMapper.selectWaitStartExam(now);
        List<Exam> waitEndExam = examMapper.selectWaitEndExam(now);
        List<StudentExamPaperVo> studentExams = studentExamService.selectByUnEnd();

//        List<Integer> studentExamIdList = new ArrayList<>();
//
//        //examId和studentId进行分组
//        List<StudentExamPaperVo> groupList = studentExamMapper.selectGroupBYExamIdAndStudentId();
//        //获取每场考试每名学生第一次参加时的数据studentExamId
//        for (StudentExamPaperVo studentExamPaperVo : groupList) {
//            StudentExamPaperVo studentExamsOne = studentExamService.selectByUnEndFirst(studentExamPaperVo.getStudentExamId(), studentExamPaperVo.getExamId());
//            studentExamIdList.add(studentExamsOne.getStudentExamId());
//        }

        for (StudentExamPaperVo studentExamPaperVo : studentExams) {
            if (studentExamPaperVo.getAnswerTime() == null) {
                Long useTime = DateUtils.pastMinutes(studentExamPaperVo.getExamStartTime());
                Long answerTime = studentExamPaperVo.getExamEndTime().getTime() - studentExamPaperVo.getExamStartTime().getTime();
                if (useTime >= answerTime) {
                    log.info("学员考试studentExamId:{}超过考试答题时间，系统后台自动交卷", studentExamPaperVo.getStudentExamId());
                    studentExamService.finishExam(studentExamPaperVo.getStudentExamId());
                }
            } else {
                Long useTime = DateUtils.pastMinutes(studentExamPaperVo.getCreateTime());
                if (useTime >= studentExamPaperVo.getAnswerTime() || DateUtils.pastMinutes(studentExamPaperVo.getExamEndTime()) >= 0) {
                    log.info("学员考试studentExamId:{}超过考试答题时间，系统后台自动交卷", studentExamPaperVo.getStudentExamId());
                    studentExamService.finishExam(studentExamPaperVo.getStudentExamId());
                }
            }
        }
        for (Exam exam : waitStartExam) {
            exam.setExamStatus(ExamStatusEnum.DOING.getValue());
            exams.add(exam);
        }
        for (Exam exam : waitEndExam) {
            exam.setExamStatus(ExamStatusEnum.AFTER.getValue());
            exams.add(exam);
        }
        log.info("开始{}场考试，结束{}场考试", waitStartExam.size(), waitEndExam.size());
        if (exams.size() > 0) {
            examMapper.updateBatch(exams);
        }
    }

    /**
     * 更新考试状态，并更新状态
     */
    public void modifyExamStatus() {
        Date now = new Date();
        List<Exam> exams = new ArrayList<>();
        List<Exam> waitStartExam = examMapper.selectStartExam(now);
        List<Exam> waitEndExam = examMapper.selectEndExam(now);
        List<Exam> beforeExam = examMapper.selectBeforeExam(now);

        for (Exam exam : waitStartExam) {
            exam.setExamStatus(ExamStatusEnum.DOING.getValue());
            exams.add(exam);
        }
        for (Exam exam : waitEndExam) {
            exam.setExamStatus(ExamStatusEnum.AFTER.getValue());
            exams.add(exam);
        }
        for (Exam exam : beforeExam) {
            exam.setExamStatus(ExamStatusEnum.BEFORE.getValue());
            exams.add(exam);
        }
        if (exams.size() > 0) {
            examMapper.updateBatch(exams);
        }
    }

}
